package cn.z2huo.knowledge.concurrency.lock.reentrantlock.dead;

import cn.hutool.core.thread.ThreadUtil;

import java.util.concurrent.locks.Lock;

/**
 * <p>
 *
 * @author z2huo
 */
class TwoLockDeadDemo {

    public static void twolockInterruptiblyLock(Lock lock, Lock lock2) {

        String lockName = lock.toString().replace("java.util.concurrent.locks.", "");
        String lock2Name = lock2.toString().replace("java.util.concurrent.locks.", "");

        // 获取第一把锁
        System.out.println(Thread.currentThread().getName() + ", try get first lock, lock name is " + lockName);
        try {
            lock.lockInterruptibly();
        } catch (InterruptedException e) {
            System.out.println(Thread.currentThread().getName() + ", try get first lock, lock name is " + lockName + " was interrupted");
            return;
        }

        try {
            // 获取到了第一把锁
            System.out.println(Thread.currentThread().getName() + ", first lock got, lock name is " + lockName);

            // 尝试获取第二把
            System.out.println(Thread.currentThread().getName() + ", try get second lock, lock name is " + lock2Name);
            try {
                lock2.lockInterruptibly();
            } catch (InterruptedException e) {
                System.out.println(Thread.currentThread().getName() + ", try get second lock, lock name is " + lock2Name + " was interrupted");
                return;
            }

            try {
                // 获取到了第二把锁
                System.out.println(Thread.currentThread().getName() + ", second lock got, lock name is " + lock2Name);
                // 业务逻辑。。。
                System.out.println("do something");
                ThreadUtil.sleep(1000);
            } finally {
                // 后获取到的第二把锁，先解锁
                lock2.unlock();
                System.out.println(Thread.currentThread().getName() + ", second lock, lock name is " + lock2Name + " was unlocked");
            }

        } finally {
            // 先获取到的第一把锁，后解锁
            lock.unlock();
            System.out.println(Thread.currentThread().getName() + ", first lock, lock name is " + lockName + " was unlocked");
        }
    }

}
